package com.dyz.wsw;

import com.dyz.wsw.domain.market.pojo.MarketCard;
import com.dyz.wsw.domain.market.service.MarketService;
import com.dyz.wsw.domain.admin.pojo.LoginLogDO;
import com.dyz.wsw.domain.admin.pojo.UserLoginInfoVO;
import com.dyz.wsw.domain.admin.repository.persist.ILoginLogRepository;
import com.dyz.wsw.domain.market.repository.persist.MarketCardRepository;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.reactive.TransactionalOperator;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 正式测试r2bc连接
 * @author dyz
 * Time 2024/6/7 23:27
 */
@SpringBootTest
public class toR2dbc {

    @Autowired
    private DatabaseClient databaseClient;

    @Autowired
    private MarketCardRepository marketCardRepository;

    @Autowired
    private ILoginLogRepository loginLogRepository;


    @Autowired
    private MarketService marketService;

    @Autowired
    private TransactionalOperator transactionalOperator;

    @Autowired
    private R2dbcEntityTemplate template;

    @Test
    public void testTransaction() throws IOException {
        template.select(MarketCard.class)
                        .all().subscribe(System.out::println);
        System.in.read();
    }


    @Test
    public void doInsert() throws IOException {
//        databaseClient.sql("insert into admin_login_log values (null,2,'user1234','1232.22','华为',now(),now(),now())")
//                .then()
//                .subscribe(System.out::println);
        LocalDateTime now = LocalDateTime.now();
        loginLogRepository.save(new LoginLogDO(null,3L,"test1","ip22","xiaomi",now,now,now))
                .subscribe(System.out::println);
        System.in.read();
    }

    @Test
    public void testDD() throws IOException {
        UserLoginInfoVO userLoginInfoVO = new UserLoginInfoVO(new ArrayList<>());
//        List<String> permissions = new ArrayList<>();
//        userLoginInfoVO1.setPermissions(permissions);
        databaseClient.sql("SELECT admin_user.id,admin_user.username," +
                "admin_user.password,admin_user.avatar,admin_user.enable," +
                "admin_user.login_count,admin_permission.value " +
                "FROM admin_user " +
                "LEFT JOIN admin_user_role ON admin_user.id=admin_user_role.user_id " +
                "LEFT JOIN admin_role_permission ON admin_user_role.role_id=admin_role_permission.role_id " +
                "LEFT JOIN admin_permission ON admin_role_permission.permission_id=admin_permission.id " +
                "WHERE username=:username")
                .bind("username","user1234")
                .fetch()
                .all()
                .collectList()
                .flatMap(list->{
                    if(!list.isEmpty()){
                        Map<String, Object> ele = list.get(0);
                        userLoginInfoVO.setId(Long.parseLong(ele.get("id").toString()));
                        userLoginInfoVO.setUsername(ele.get("username").toString());
                        userLoginInfoVO.setPassword(ele.get("password").toString());
                        userLoginInfoVO.setAvatar(ele.get("avatar").toString());
                        userLoginInfoVO.setEnable(Integer.parseInt(ele.get("enable").toString()));
                        userLoginInfoVO.setLoginCount(Integer.parseInt(ele.get("login_count").toString()));
                        for (Map<String, Object> stringObjectMap : list) {
                            userLoginInfoVO.getPermissions().add(stringObjectMap.get("value").toString());
                        }
                        return Mono.just(userLoginInfoVO);
                    }else {
                        return Mono.empty();
                    }
                })
//                .reduce(new UserLoginInfoVO(new ArrayList<>()),(userLoginInfoVO,ele)->{
//                    userLoginInfoVO.setId(Long.parseLong(ele.get("id").toString()));
//                    userLoginInfoVO.setUsername(ele.get("username").toString());
//                    userLoginInfoVO.setPassword(ele.get("password").toString());
//                    userLoginInfoVO.setAvatar(ele.get("avatar").toString());
//                    userLoginInfoVO.setEnable(Integer.parseInt(ele.get("enable").toString()));
//                    userLoginInfoVO.setLoginCount(Integer.parseInt(ele.get("login_count").toString()));
//                    userLoginInfoVO.getPermissions().add(ele.get("value").toString());
//                    return userLoginInfoVO;
//                })
                .subscribe((v)->{
                    System.out.println(v);
                });

        System.in.read();
    }

    @Test
    public void testConnNavigationMenu() throws IOException {
//        navigationMenuRepository.findAll()
//                .subscribe(System.out::println);

//        Mono.zip(Mono.just(1),Mono.just(2),(a, b)->{
//            System.out.println(a);
//            System.out.println(b);
//            return a+b;
//        }).subscribe(System.out::println);

//        Flux.interval(Duration.ofSeconds(1))//每秒发出一个信号
//                        .map(tick-> {
//                            Instant utc = Instant.now();
//                            ZoneId zoneId = ZoneId.of("Asia/Shanghai");
//                            ZonedDateTime zonedDateTime = utc.atZone(zoneId);
//
//                            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//                            return zonedDateTime.format(formatter);
//                        })//将信号转换为当前时间戳
//                        .take(10)//只取前10个
//                        .subscribe(System.out::println);
        System.in.read();
    }

    @Test
    public void validPassword() throws IOException {
        String username="admin123";
        databaseClient.sql("select password from user where username=?")
                .bind(0,username)
                .fetch()
                .one()
                .subscribe((r)->{
                    String password = r.get("password").toString();

                });

        System.in.read();
    }
    @Test
    public void testEncrypt(){
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String result = encoder.encode("Admin123");
        System.out.println(result);
        System.out.println(encoder.matches("admin123","$2a$10$UC70IEmVsbEajVWCH8c/HujbD22Nqhfm7s70jPE6qv5dq/GWmL93m"));
    }

    @Test
    public void testRandomAccess() throws IOException {
        databaseClient.sql("select max(id) max_id from front_market_module")
                .fetch()
                .one()
                .flatMap(data->{
                    int maxId = Integer.parseInt(data.get("max_id").toString());
                    Random random = new Random();
                    Set<Integer> uniqueNumbers = new HashSet<>();
                    while (uniqueNumbers.size()<8){
                        uniqueNumbers.add(random.nextInt( maxId)+1);
                    }
                    System.out.println(uniqueNumbers);
                    StringBuilder sb = new StringBuilder();
                    List<Integer> values = uniqueNumbers.stream().toList();

                    return databaseClient.sql("select * from front_market_module where id in (:values)")
                            .bind("values", values)
                            .fetch()
                            .all().collectList();
                })
                .flatMap(list->{
                    for (int i = 0; i < list.size(); i++) {
                        Map<String, Object> s = list.get(i);
                    }
                    return Mono.empty();
                })
                .subscribe((r)->{
                    System.out.println(r);
                });
        System.in.read();
    }


    @Test
    public void random8(){
        Random random = new Random();
        Set<Integer> uniqueNumbers = new HashSet<>();
        while (uniqueNumbers.size()<8){
            uniqueNumbers.add(random.nextInt(16+1));
        }
        System.out.println(uniqueNumbers);
    }


    @Test
    public void testR2() throws IOException {
    }


}
